#include "mystdio.h"
#include <string.h>
#include <fcntl.h>
#include <malloc.h>
#include <unistd.h>
#include <assert.h>
MY_FILE* my_fopen(const char* path,const char* mode)  //fopen函数本质调用open函数
{
    int flags = 0;  //打开文件的方式
    //1.根据mode指令"r" "w" "a"不同，设置不同的打开方式flags
    if(strcmp(mode,"r") == 0)
      flags = O_RDONLY;
    else if(strcmp(mode,"w") == 0)
      flags = (O_CREAT | O_WRONLY | O_TRUNC);
    else if(strcmp(mode,"a") == 0)
      flags = (O_CREAT | O_WRONLY | O_APPEND);
     
    int fd = 0;
    mode_t m = 0666;  //创建文件时，指定文件的权限
    //2.根据不同的flags不同open打开方式
    if(flags & O_RDONLY)
      fd = open(path,flags);
    else if(flags & O_WRONLY)
      fd = open(path,flags,m);
    else 
    {//其他的打开方式：a+、r+、w+
            
    }
    //打开失败
    if(fd == -1) 
    {
      perror("open file");
      return NULL;
    }

    //3.打开成功，将数据以MY_FILE类型返回
    MY_FILE* mf = (MY_FILE*)malloc(sizeof(MY_FILE));  //动态创建
    mf->fd = fd;   //获取文件标识符
   //mf->flags = BUFF_LINE; //指定缓冲刷新策略 ->行缓冲
    mf->flags = BUFF_ALL;
    mf->current = 0; //开始写入的位置
    memset(mf->outputbuffer,'\0',sizeof(mf->outputbuffer));  //初始化为'\0'
   // mf->outputbuffer = 0;
  return mf;
}
int my_fflush(MY_FILE* stream)
{
     assert(stream);
     write(stream->fd,stream->outputbuffer,sizeof(stream->outputbuffer));
     stream->current = 0;
     return 0;
}
size_t my_fwrite(const void *ptr,size_t size,size_t nmemb,MY_FILE *stream)
{
    
       //1.首先要考虑写入数据的大小及缓冲区还剩的空间-->首先写入缓冲区
       size_t mysize = NUM - stream->current;  //缓冲区所剩的空间大小
       size_t user_size = size*nmemb;   //要写入的数据大小
       size_t st = 0;    //记录真实写入的数据
       if(mysize > user_size)
       {
        memcpy(stream->outputbuffer+stream->current,ptr,user_size);
        st = user_size;
        stream->current += user_size;
       }
       else 
       {
        memcpy(stream->outputbuffer+stream->current,ptr,mysize);
        st = mysize;
        stream->current += mysize;
       }

       //2.刷新策略
       if(stream->flags == BUFF_NONE)
       {
         my_fflush(stream);
       }else if(stream->flags == BUFF_LINE)
       {
         if(stream->outputbuffer[stream->current-1] == '\n')
         {
           my_fflush(stream);
         }
       }else if(stream->flags == BUFF_ALL)
       {
         if(stream->current >= NUM)
         {
           my_fflush(stream);
         }
       }
       return st;
 }
int my_fclose(MY_FILE *fp)
{
    assert(fp);
   if(close(fp->fd) == -1) return -1;
    free(fp);
    fp = NULL;
    return 1;
}
